package com.nineclock.approve.service.impl;

import cn.hutool.json.JSONArray;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.nineclock.approve.activiti.ProcessNodeResolver;
import com.nineclock.approve.activiti.impl.ProcessNodeResolverFactory;
import com.nineclock.approve.pojo.ApproveDefinition;
import com.nineclock.approve.service.ActivitiService;
import lombok.extern.slf4j.Slf4j;
import org.activiti.bpmn.BpmnAutoLayout;
import org.activiti.bpmn.converter.BpmnXMLConverter;
import org.activiti.bpmn.model.BpmnModel;
import org.activiti.bpmn.model.Process;
import org.activiti.engine.RepositoryService;
import org.activiti.engine.repository.ProcessDefinition;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

@Service
@Slf4j
public class ActivitiServiceImpl implements ActivitiService {
    @Autowired
    private RepositoryService repositoryService;
	
    @Override
    public void deployProcessToActiviti(ApproveDefinition definition) {
        //1. 构建BpmnModel
        BpmnModel bpmnModel = new BpmnModel();

        //2. 创建Process
        Process process = new Process();
        process.setId("process_"+definition.getId());
        process.setName(definition.getName());

        //3. 创建流程节点(开始节点, 审批节点, 网关节点 , 抄送节点,  结束节点)
        JSONArray flowArray = JSONUtil.parseArray(definition.getFlowJson());
        addNodesToProcess(process, flowArray);

        //4. 设置Process到BpmnModel
        bpmnModel.addProcess(process);

        //5. 自动布局BpmnModel
        new BpmnAutoLayout(bpmnModel).execute();

        //6. 部署构建的审批流程BpmnModel到Activiti
        repositoryService.createDeployment()
                .name(definition.getName())
                .addBpmnModel(definition.getName()+".bpmn", bpmnModel)
                .deploy();
		
        //输出XML, 便于测试
        BpmnXMLConverter converter = new BpmnXMLConverter();
        byte[] bytes = converter.convertToXML(bpmnModel);

        log.info("-------> 转换BpmnModel为XML数据 .");
        System.out.println(new String(bytes));
        log.info("-------> XML文件转换并输出完毕 . ");
    }

    @Override
    public void dropProcessFromActiviti (ApproveDefinition definition){
        //根据流程 key查询流程
        ProcessDefinition processDefinition = repositoryService.createProcessDefinitionQuery().processDefinitionKey("process_" + definition.getId()).singleResult();
        //根据 id删除 流程
        repositoryService.deleteDeployment(processDefinition.getDeploymentId());
    }

    //构建节点, 添加到process中
    private void addNodesToProcess(Process process, JSONArray flowArray) {

        for (int i = 0; i < flowArray.size(); i++) {
            JSONObject currNode = (JSONObject) flowArray.get(i);
            JSONObject nextNode = null;
            
            if(i < flowArray.size()-1){
                nextNode = (JSONObject)flowArray.get(i+1);
            }

            //传递当前节点 , 下一个节点, 进行流程绘制 ------> 不同的节点类型调用的API不同, 绘制的方式不同 , 需要根据type来决定
			//TODO
            ProcessNodeResolver nodeResolver = ProcessNodeResolverFactory.getInstance(currNode.getStr("type"));
            nodeResolver.addFlowNodeToActiviti(process,currNode,nextNode);
            
        }
    }
}